﻿using System;
using System.Windows.Forms;
using SampleMessages;
using SimpleServiceBus.Bus;
using SimpleServiceBus.Endpoint;
using SimpleServiceBus.Endpoints.Msmq;
using SimpleServiceBus.Endpoints.Msmq.Configuration;
using SimpleServiceBus.StructureMap;
using SimpleServiceBus.Utilities;
/*
 * This sample uses the StructureMap object builder, rather than the reflection based default object builder.
 * 
 */

namespace SampleManagedEndpoint
{
    internal delegate void NotifyDelegate(string message);

    public partial class MainForm : Form
    {
        private IMessagingEndpoint _endpoint;

        public MainForm()
        {
            InitializeComponent();
        }

        public static MainForm Current { get; set; }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            Current = this;
            btnStartStop_Click(null, null);
        }

        private void CreateEndpoint()
        {
            MsmqHelper.EnsureQueue("ManagedClient");
            MsmqHelper.EnsureQueue("EndpointMonitorService");

            //Create the endpoint
            _endpoint = MsmqEndpointConfiguration.CreateConfiguredEndpoint(new StructureMapObjectBuilder(),
                                                                           GetType().Assembly);

            //We want to log messages coming in and out of this endpoint to a textbox, so we need to pay attention to some events.
            _endpoint.MessageBus.MessageSent += MessageBus_MessageSent;
            _endpoint.MessageBus.MessageReceived += MessageBus_MessageReceived;

            //Let's also make note of any errors...
            _endpoint.MessageBus.MessageProcessingException += MessageBus_MessageProcessingException;
        }

        void MessageBus_MessageProcessingException(object sender, MessageProcessingErrorEventArgs e)
        {
            Notify("A problem was encountered processing a message: " + e.Exception.FullMessage());
        }

        void MessageBus_MessageReceived(object sender, MessageProcessingEventArgs e)
        {
            LogMessage(String.Format("{0}:{1} {2}@{3}", e.Message.Body.GetType(), e.Message.MessageID, "Received", DateTime.Now));
        }

        void MessageBus_MessageSent(object sender, MessageProcessingEventArgs e)
        {
            LogMessage(String.Format("{0}:{1} {2}@{3}", e.Message.Body.GetType(), e.Message.MessageID, "Sent", DateTime.Now));
        }


        private void StartEndpoint()
        {
            Notify("Starting Endpoint");

            _endpoint.Start();

           Notify("Endpoint Started");
            btnStartStop.Text = "Stop";
        }

        private void StopEndpoint()
        {
            Notify("Stopping Endpoint");

            _endpoint.Stop();

            Notify("Endpoint Stopped");
            btnStartStop.Text = "Start";
        }

        public void Notify(string message)
        {
            if (InvokeRequired)
            {
                NotifyDelegate marshal = Notify;
                BeginInvoke(marshal, message);
            }
            else
            {
                txtStatus.Text += message + Environment.NewLine;
                txtStatus.Refresh();
            }
        }

        public void LogMessage(string message)
        {
            if (InvokeRequired)
            {
                NotifyDelegate marshal = LogMessage;
                BeginInvoke(marshal, message);
            }
            else
            {
                txtMessageLog.Text += message + Environment.NewLine;
                txtMessageLog.Refresh();
            }
        }

        private void btnStartStop_Click(object sender, EventArgs e)
        {
            try
            {
                if (_endpoint == null)
                {
                    CreateEndpoint();
                }

                if (_endpoint.IsRunning)
                {
                    StopEndpoint();
                }
                else
                {
                    StartEndpoint();
                }
            }
            catch (Exception ex)
            {
                Notify(ex.Message + Environment.NewLine + ex.StackTrace);
                while (ex.InnerException != null)
                {
                    Notify(ex.InnerException.Message + Environment.NewLine + ex.StackTrace);
                    ex = ex.InnerException;
                }
            }
        }

        private void btnPublish_Click(object sender, EventArgs e)
        {
            if (_endpoint != null &&
                _endpoint.IsRunning)
            {
                _endpoint.MessageBus.Publish(new TestPublicationMessage
                {
                    EventTime = DateTime.Now,
                    Message = txtPubSubMessage.Text
                });
                Notify("Message Published");
                //txtPubSubMessage.Text = String.Empty;
            }
        }
    }
}